#pragma once

#include <AST/ExprAST.hpp>
#include <llvm/IR/InstrTypes.h>

class BinaryOp : public Expr {
    // 操作符类型
    OpType opType;

    // 两个操作数
    Expr *lhs, *rhs;

    // 返回值类型
    // Type *resultType = nullptr;

  public:
    BinaryOp(OpType opType, Expr *lhs, Expr *rhs);

    virtual Value *codegen() override;

    static BinaryOp *assign(Expr *lhs, Expr *rhs) {
        return new BinaryOp(OpType::Assign, lhs, rhs);
    }

    friend class graphviz::GraphGenerator;

    virtual VisitResult accept(ASTVisitor &visitor) const override {
        return visitor.visitBinaryOpAST(this);
    }

    inline OpType getOpType() const { return opType; }

  private:
    Value *floatingCodegen(Value *L, Value *R, Type *type);
    Value *integerCodegen(Value *L, Value *R, Type *type);
    Value *assignCodegen();
    Value *boolCodegen(Value *L, Value *R);
};